import numpy as np
import matplotlib.pyplot as plt

# 鸢尾花数据集读取
from sklearn.datasets import load_iris
data = load_iris()
x = data.data
y = data.target

# scale
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x = scaler.fit_transform(x)

# 数据切分为训练集和测试集
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.7, random_state=666)

# 使用网格搜索交叉验证处理逻辑回归
# 设置的参数有  L1正则L2正则    正则化分别取 0.1， 0.2， 0.5， 1
# 打印模型最优参数和得分
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegression
import sys, os, pickle
fixed_params = dict(solver='liblinear',
                    max_iter=1000,
                    multi_class='auto')
ver = 'v1.0'
path = sys.argv[0] + '_' + ver + '.tmp.dat'
if os.path.exists(path):
    with open(path, 'br') as f:
        best_params = pickle.load(f)
    print('LOADED.')
else:
    print('Grid searching ...')
    estimator = LogisticRegression(**fixed_params)
    params = dict(C=[0.1, 0.25, 0.33, 0.4, 0.5, 1])
    grid = GridSearchCV(estimator, params, cv=5, iid=True)
    grid.fit(x_train, y_train)
    print(f'best score = {grid.best_score_}')
    best_params = grid.best_params_
    with open(path, 'bw') as f:
        pickle.dump(best_params, f)

print(f'best params = {best_params}')

# 使用最优参数和得分训练模型
# 打印测试集得分
model = LogisticRegression(**fixed_params,
                           **best_params)
model.fit(x_train, y_train)
print(f'Training score = {model.score(x_train, y_train)}')
print(f'Testing score = {model.score(x_test, y_test)}')

# ROC
import math
proba_test = model.predict_proba(x_test)
n_cls = len(proba_test[0])
spr = math.floor(math.sqrt(n_cls))
if spr < 1:
    spr = 1
spc = math.ceil(n_cls / spr)
spr = int(spr)
spc = int(spc)
spn = 0
scale = 3
plt.figure(figsize=[scale*spc, scale*spr])
print(f'spr={spr}, spc={spc}')

from sklearn.metrics import roc_curve, roc_auc_score
for cls in range(n_cls):
    spn += 1
    plt.subplot(spr, spc, spn)
    plt.title(f'Class {cls}')
    print(f'roc auc score = {roc_auc_score(y_test == cls, proba_test[:, cls])}')
    fpr, tpr, th = roc_curve(y_test == cls, proba_test[:, cls])  # ValueError: multiclass format is not supported
    plt.plot(fpr, tpr)
    for i, t in enumerate(th):
        plt.annotate(f'{t:.2f}', xy=[fpr[i], tpr[i]])

# show all drawings
plt.show()
